/*
 ============================================================================
 Name		: IapManager.cpp
 Author	  : Livy
 Version	 : 1.0
 Copyright   : BUPT
 Description : CIapManager implementation
 ============================================================================
 */

#include "IapManager.h"
#include <cdbpreftable.h>
#include <rconnmon.h>
#include <cdbstore.h>
#include <commdbconnpref.h>
#include <es_enum.h>

#include "PhoneInfo.h"

void IapManager::CreateIap(const TDesC& aIapName, TUint32& aIapId)
	{
	CCommsDatabase* commsDb = CCommsDatabase::NewL();
	CleanupStack::PushL(commsDb);
	TUint32 network_id;
	commsDb->BeginTransaction();
	/* Step 1 */
	// creating a new network record
	CCommsDbTableView* network = commsDb->OpenTableLC(TPtrC(NETWORK));
	network->InsertRecord(network_id);
	network->WriteTextL(TPtrC(COMMDB_NAME), aIapName);
	network->PutRecordChanges();
	CleanupStack::PopAndDestroy(network);

	/* Step 2 */
	// creating a new outgoing gprs record
	TUint32 og_gprs_id;
	// See implementations in the CreateNewOgGprsL function
	TInt err = CreateNewOgGprsL(*commsDb, aIapName, og_gprs_id);

	/* Step 3 */
	// creating a new wap accesspoint record
	TUint32 ap_id;
	// See implementations in the CreateNewAccessPointL function
	err = CreateNewAccessPointL(*commsDb, aIapName, ap_id);

	/* Step 4 */
	// creating a new IAP record
	CCommsDbTableView* iap = commsDb->OpenTableLC(TPtrC(IAP));

	//TUint32 iap_id;
	err = iap->InsertRecord(aIapId);

	iap->WriteTextL(TPtrC(COMMDB_NAME), aIapName);

	iap->WriteUintL(TPtrC(IAP_SERVICE), og_gprs_id);

	iap->WriteTextL(TPtrC(IAP_SERVICE_TYPE), TPtrC(OUTGOING_GPRS));

	iap->WriteTextL(TPtrC(IAP_BEARER_TYPE), TPtrC(MODEM_BEARER));

	// In real application, don't hard-code. Should check from the modem bearer
	iap->WriteUintL(TPtrC(IAP_BEARER), 2);

	iap->WriteUintL(TPtrC(IAP_NETWORK), network_id);
	iap->WriteUintL(TPtrC(IAP_NETWORK_WEIGHTING), 0);

	iap->WriteUintL(TPtrC(IAP_LOCATION), 2);

	iap->PutRecordChanges();
	CleanupStack::PopAndDestroy(iap);

	/* Step 5 */
	// creating a new wap bearer
	CCommsDbTableView* wap_bearer = commsDb->OpenTableLC(TPtrC(WAP_IP_BEARER));

	TUint32 wb_id;
	wap_bearer->InsertRecord(wb_id);

	wap_bearer->WriteUintL(TPtrC(WAP_ACCESS_POINT_ID), ap_id);
	_LIT(wap_gw_address, "0.0.0.0");
	wap_bearer->WriteTextL(TPtrC(WAP_GATEWAY_ADDRESS), wap_gw_address);

	wap_bearer->WriteUintL(TPtrC(WAP_IAP), aIapId);

	wap_bearer->WriteUintL(TPtrC(WAP_WSP_OPTION),
			EWapWspOptionConnectionOriented);

	wap_bearer->WriteBoolL(TPtrC(WAP_SECURITY), EFalse);
	wap_bearer->WriteUintL(TPtrC(WAP_PROXY_PORT), 0);

	wap_bearer->PutRecordChanges();
	CleanupStack::PopAndDestroy(wap_bearer);
	///////////////////////////////////////////////////////////////
    _LIT(KIP,"10.0.0.172");
    TUint32 proxiesId;
    //CCommsDatabase* cdb7=CCommsDatabase::NewL(EDatabaseTypeIAP);
    //CleanupStack::PushL(cdb7);
    CCommsDbTableView* view7 = commsDb->OpenTableLC(TPtrC(PROXIES));

    User::LeaveIfError(view7->InsertRecord(proxiesId));

    view7->WriteUintL(TPtrC(PROXY_ISP), og_gprs_id); // gprsId == iIapId
    //view7->WriteUintL(TPtrC(PROXY_ISP), iIapId); // gprsId == iIapId
    view7->WriteTextL(TPtrC(PROXY_SERVICE_TYPE), TPtrC(OUTGOING_GPRS));
    view7->WriteBoolL(TPtrC(PROXY_USE_PROXY_SERVER), ETrue);
    view7->WriteLongTextL(TPtrC(PROXY_SERVER_NAME), KIP);
    view7->WriteTextL(TPtrC(PROXY_PROTOCOL_NAME), _L("http"));
    view7->WriteUintL(TPtrC(PROXY_PORT_NUMBER), 80);

    TInt error = view7->PutRecordChanges();

    CleanupStack::PopAndDestroy(view7);

	//////////////////////////////////////////////////////////////////////////

	// Finish

	err = commsDb->CommitTransaction();
	CleanupStack::PopAndDestroy(commsDb); // commsDb
	}

TInt IapManager::CreateNewOgGprsL(CCommsDatabase& aCommsDb,
		const TDesC& aCommsdb_name_val, TUint32& aOgGprsId)
	{
	CCommsDbTableView* commsOgGprs = aCommsDb.OpenTableLC(TPtrC(OUTGOING_GPRS));

	TInt err = commsOgGprs->InsertRecord(aOgGprsId);

	commsOgGprs->WriteTextL(TPtrC(COMMDB_NAME), aCommsdb_name_val);

	commsOgGprs->WriteLongTextL(TPtrC(GPRS_APN), aCommsdb_name_val);

	commsOgGprs->WriteUintL(TPtrC(GPRS_PDP_TYPE), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_REQ_PRECEDENCE), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_REQ_DELAY), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_REQ_RELIABILITY), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_REQ_PEAK_THROUGHPUT), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_REQ_MEAN_THROUGHPUT), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_MIN_PRECEDENCE), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_MIN_DELAY), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_MIN_RELIABILITY), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_MIN_PEAK_THROUGHPUT), 0);

	commsOgGprs->WriteUintL(TPtrC(GPRS_MIN_MEAN_THROUGHPUT), 0);

	commsOgGprs->WriteBoolL(TPtrC(GPRS_DATA_COMPRESSION), EFalse);

	commsOgGprs->WriteBoolL(TPtrC(GPRS_HEADER_COMPRESSION), EFalse);

	commsOgGprs->WriteBoolL(TPtrC(GPRS_ANONYMOUS_ACCESS), EFalse);

	commsOgGprs->WriteTextL(TPtrC(GPRS_IF_NETWORKS), _L("ip"));

	commsOgGprs->WriteBoolL(TPtrC(GPRS_IF_PROMPT_FOR_AUTH), EFalse);

	commsOgGprs->WriteUintL(TPtrC(GPRS_IF_AUTH_RETRIES), 0);

	commsOgGprs->WriteTextL(TPtrC(GPRS_IP_GATEWAY), _L("0.0.0.0"));

	// True 才能联网
	commsOgGprs->WriteBoolL(TPtrC(GPRS_IP_DNS_ADDR_FROM_SERVER), ETrue);

	commsOgGprs->WriteTextL(TPtrC(GPRS_IP_NAME_SERVER1), _L("0.0.0.0"));
	commsOgGprs->WriteTextL(TPtrC(GPRS_IP_NAME_SERVER2), _L("0.0.0.0"));

	commsOgGprs->WriteBoolL(TPtrC(GPRS_ENABLE_LCP_EXTENSIONS), EFalse);

	// 鉴定级别：普通、安全
	commsOgGprs->WriteBoolL(TPtrC(GPRS_DISABLE_PLAIN_TEXT_AUTH), ETrue);

	commsOgGprs->WriteBoolL(TPtrC(GPRS_IP_ADDR_FROM_SERVER), ETrue);
	commsOgGprs->WriteUintL(TPtrC(GPRS_AP_TYPE), 2);

	commsOgGprs->WriteUintL(TPtrC(GPRS_QOS_WARNING_TIMEOUT), -1);

	commsOgGprs->PutRecordChanges();
	CleanupStack::PopAndDestroy(commsOgGprs);

	return KErrNone;
	}

TInt IapManager::CreateNewAccessPointL(CCommsDatabase& aCommsDb,
		const TDesC& aCommsdb_name_val, TUint32& aApId)
	{
	CCommsDbTableView* commsAp = aCommsDb.OpenTableLC(TPtrC(WAP_ACCESS_POINT));

	commsAp->InsertRecord(aApId);

	commsAp->WriteTextL(TPtrC(COMMDB_NAME), aCommsdb_name_val);

	commsAp->WriteTextL(TPtrC(WAP_CURRENT_BEARER), TPtrC(WAP_IP_BEARER));

	commsAp->WriteTextL(TPtrC(WAP_START_PAGE), _L(""));//http://monternet.com

	commsAp->PutRecordChanges();

	CleanupStack::PopAndDestroy(commsAp);

	return KErrNone;
	}

TBool IapManager::SearchIap(const TDesC& aIapName, TUint32& aIapId)
	{
	// open commdb
	TBool ret = EFalse;
	CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(commDb);

	// open IAP table
	CCommsDbTableView* commView = commDb->OpenIAPTableViewMatchingBearerSetLC(
			ECommDbBearerGPRS, ECommDbConnectionDirectionOutgoing);

	TBuf<KCommsDbSvrMaxFieldLength> dbname;
	TInt returnValue = 0;

	returnValue = commView->GotoFirstRecord();

	//	TInt deleteValue = 0;

	while (returnValue == KErrNone)
		{
		commView->ReadTextL(TPtrC(COMMDB_NAME), dbname);
		dbname.LowerCase();
		if (dbname.Compare(aIapName) == 0)
			{
			commView->ReadUintL(TPtrC(COMMDB_ID), aIapId);
			ret = ETrue;
			break;
			}
		returnValue = commView->GotoNextRecord();
		}

	CleanupStack::PopAndDestroy(commView);
	CleanupStack::PopAndDestroy(commDb);
	return ret;
	}
void IapManager::GetIap(TUint32& aIapId, TIapType aType)
	{
	TBuf<20> typeName;
	if (aType == EIapCmnet)
		{
		typeName.Copy(_L("cmnet"));
		}
	else if (aType == EIapCmwap)
		{
		typeName.Copy(_L("cmwap"));
		}
	else if (aType == EIapUninet)
		{
		typeName.Copy(_L("uninet"));
		}
	else if (aType == EIapUniwap)
		{
		typeName.Copy(_L("uniwap"));
		}
#ifdef __WINSCW__
	typeName.Copy(_L("winsock"));
#endif
	if (!SearchIap(typeName, aIapId))
		{
		CreateIap(typeName, aIapId);
		}
	}
void IapManager::AutoGetIap(TUint32& aIapId)
	{
	//	TNetWorkType netType = CPhoneInfo::GetNetWorkType();
	//	if (netType == ENetWorkCM)
	//	{
	//		GetIap(aIapId, EIapCmwap);
	//	}
	//	else if (netType == ENetWorkUN)
	//	{
	//		GetIap(aIapId, EIapUniwap);
	//	}
	//	else
	//	{
	//		aIapId = KMaxTUint32;
	//	}
#ifdef __WINSCW__
	aIapId = 0;
#else
#ifdef EKA2
	TNetWorkType netType = CPhoneInfo::GetNetWorkType();
	if (netType == ENetWorkCM)
		{
		GetIap(aIapId, EIapCmnet);
		}
	else if (netType == ENetWorkUN)
		{
		GetIap(aIapId, EIapUninet);
		}
	else
		{
		aIapId = KMaxTUint32;
		}
#else
	GetIap(aIapId, EIapCmwap);
#endif
#endif		
	}

//void IapManager::ListNetworksAndSignalL(CDesCArraySeg& aNetworks)
//{
//	_LIT(KNetInfo, "%S:%d");
//	TBuf<32> netName;
//	TBuf<100> line;
//	RConnectionMonitor monitor;
//	TPckgBuf<TConnMonNetworkNames> pkgNetworks;
//
//	// establish connection with the monitor server
//	monitor.ConnectL();
//	// prepare leave clean-up
//	CleanupClosePushL(monitor);
//	TRequestStatus status;
//	// get the list of available networks
//	monitor.GetPckgAttribute(EBearerIdWLAN, 0, KNetworkNames, pkgNetworks, status);
//
//	// suspend thread until the info is retrieved
//	// production code should use active objects
//	User::WaitForRequest(status);
//	// leave if the asynchronous method returned an error
//	User::LeaveIfError(status.Int());
//	//  reset networks list
//	aNetworks.Reset();
//	RFs fs;
//	fs.Connect();
//	RFile file;
//	file.Replace(fs, _L("e:\\data\\networkinfo.txt"), EFileWrite);
//	TFileText fileText;
//	fileText.Set(file);
//	// add retrieved networks to the list
//	for (TUint i = 0; i < pkgNetworks().iCount; i++)
//	{
//		netName.Copy(pkgNetworks().iNetwork[i].iName);
//		line.Format(KNetInfo, &netName, pkgNetworks().iNetwork[i].iSignalStrength);
//		aNetworks.AppendL(line);
//
//		fileText.Write(line);
//	}
//
//	file.Close();
//	fs.Close();
//	// close server session
//	CleanupStack::PopAndDestroy(&monitor);
//}

void IapManager::ListAvailabilityIapL(RArray<TUint32>& aIapList)
	{
#ifdef EKA2
	RConnectionMonitor monitor;
	TPckgBuf<TConnMonIapInfo> iapInfo;

	// establish connection with the monitor server
	monitor.ConnectL();
	// prepare leave clean-up
	CleanupClosePushL(monitor);
	TRequestStatus status;
	// get the list of available networks
	monitor.GetPckgAttribute(EBearerIdAll, 0, KIapAvailability, iapInfo, status);
	// suspend thread until the info is retrieved
	// production code should use active objects
	User::WaitForRequest(status);
	// leave if the asynchronous method returned an error
	User::LeaveIfError(status.Int());
	//  reset networks list
	aIapList.Reset();

	// add retrieved networks to the list
	for (TUint i = 0; i < iapInfo().iCount; i++)
		{
		aIapList.Append(iapInfo().iIap[i].iIapId);
		}
	// close server session
	CleanupStack::PopAndDestroy(&monitor);
#endif
	}
void IapManager::GetAllIapList(RArray<TIapInfo>& aIapInfoList)
	{
	aIapInfoList.Reset();
	CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(commDb);
	CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(IAP));
	if (commView->GotoFirstRecord() == KErrNone)
		{
		do
			{
			TIapInfo iapInfo;
			commView->ReadUintL(TPtrC(COMMDB_ID), iapInfo.iId);
			commView->ReadTextL(TPtrC(COMMDB_NAME), iapInfo.iIapName);
			aIapInfoList.Append(iapInfo);
			}
		while (commView->GotoNextRecord() == KErrNone);
		}
	CleanupStack::PopAndDestroy(commView);
	CleanupStack::PopAndDestroy(commDb);
	}
void IapManager::GetAvailabilityIapList(RArray<TIapInfo>& aIapInfoList)
	{
	aIapInfoList.Reset();
	RArray<TUint32> availableIapList;
	CleanupClosePushL(availableIapList);
	ListAvailabilityIapL(availableIapList);

	TUint32 iap;
	CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(commDb);
	CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(IAP));
	if (commView->GotoFirstRecord() == KErrNone)
		{
		do
			{
			commView->ReadUintL(TPtrC(COMMDB_ID), iap);
			for (TInt i = availableIapList.Count() - 1; i >= 0; i--)
				{
				if (availableIapList[i] == iap)
					{
					TIapInfo iapInfo;
					iapInfo.iId = iap;
					commView->ReadTextL(TPtrC(COMMDB_NAME), iapInfo.iIapName);
					aIapInfoList.AppendL(iapInfo);
					break;
					}
				}

			}
		while (commView->GotoNextRecord() == KErrNone);
		}
	CleanupStack::PopAndDestroy(commView);
	CleanupStack::PopAndDestroy(commDb);
	CleanupStack::PopAndDestroy(&availableIapList);
	}

void IapManager::GetWlanIapList(RArray<TWlanInfo>& aIapInfoList)
	{
	//#ifdef EKA2
	//	{
	//		TBuf<KCommsDbSvrMaxFieldLength> commdbName;
	//		TBuf<KCommsDbSvrMaxColumnNameLength> wlanSSID;
	//
	//		//	获得接入点名字
	//		CCommsDatabase *commsDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	//		CleanupStack::PushL(commsDb);
	//		CCommsDbTableView *tableView = commsDb->OpenTableLC(_L("WLAN_SERVICE"));
	//		TInt err = tableView->GotoFirstRecord();
	//		while (err == KErrNone)
	//		{
	//			tableView->ReadTextL(TPtrC(WLAN_SSID), wlanSSID);
	//			wlanSSID.LowerCase();
	//			tableView->ReadTextL(TPtrC(WLAN_PROFILE), commdbName);
	//			TWlanInfo info;
	//			info.iIapInfo.iIapName.Copy(commdbName);
	//			info.iWlanSSID.Copy(wlanSSID);
	//			aIapInfoList.Append(info);
	//
	//			err = tableView->GotoNextRecord();
	//		}
	//		CleanupStack::PopAndDestroy(2, commsDb); // tableView, commsDb
	//	}
	//
	//	{
	//		TBuf<KCommsDbSvrMaxFieldLength> commdbName;
	//		TBuf<KCommsDbSvrMaxColumnNameLength> wlanSSID;
	//
	//		//	获得接入点名字
	//		CCommsDatabase *commsDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	//		CleanupStack::PushL(commsDb);
	//		CCommsDbTableView *tableView = commsDb->OpenTableLC(_L("WLAN_SERVICE"));
	//		TInt err = tableView->GotoFirstRecord();
	//		while (err == KErrNone)
	//		{
	//			tableView->ReadTextL(TPtrC(WLAN_SSID), wlanSSID);
	//			wlanSSID.LowerCase();
	//			tableView->ReadTextL(TPtrC(WLAN_PROFILE), commdbName);
	//			TWlanInfo info;
	//			info.iIapInfo.iIapName.Copy(commdbName);
	//			info.iWlanSSID.Copy(wlanSSID);
	//			aIapInfoList.Append(info);
	//
	//			err = tableView->GotoNextRecord();
	//		}
	//		CleanupStack::PopAndDestroy(2, commsDb); // tableView, commsDb
	//	}
	//#endif
	}

TBool IapManager::CheckIAPNameID(const TDesC& aName, TInt aIAP)
	{
	TBool flag = EFalse;
	TUint32 iap;
	TBuf<KCommsDbSvrMaxFieldLength> IAPName;
	TBuf<KCommsDbSvrMaxFieldLength> COMMDB_Name;
	CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(commDb);
	CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(IAP));
	if (commView->GotoFirstRecord() == KErrNone)
		{
		do
			{
			commView->ReadUintL(TPtrC(COMMDB_ID), iap);
			if (iap == aIAP)
				{
				commView->ReadTextL(TPtrC(COMMDB_NAME), IAPName);
				break;
				}
			}
		while (commView->GotoNextRecord() == KErrNone);
		}
	CleanupStack::PopAndDestroy(commView);

	commView = commDb->OpenTableLC(TPtrC(OUTGOING_GPRS));
	TInt err = commView->GotoFirstRecord();
	while (err == KErrNone)
		{
		TBuf<KCommsDbSvrMaxColumnNameLength> apn;
		commView->ReadTextL(TPtrC(GPRS_APN), apn);
		apn.LowerCase();
		if (apn.Find(aName) != KErrNotFound)
			{
			commView->ReadTextL(TPtrC(COMMDB_NAME), COMMDB_Name);
			if (IAPName == COMMDB_Name)
				{
				flag = ETrue;
				}
			else
				{
				flag = EFalse;
				}
			break;
			}
		err = commView->GotoNextRecord();
		}
	CleanupStack::PopAndDestroy(commView);
	CleanupStack::PopAndDestroy(commDb);
	return flag;
	}

void IapManager::GetGPRSIapList(RArray<TIapInfo>& aIapInfoList)
	{
	_LIT(KCMWAP,"cmwap");
	_LIT(KCMNET,"cmnet");
	_LIT(K3GWAP,"3gwap");
	_LIT(K3GNET,"3gnet");
	_LIT(KUNIWAP,"uniwap");
	_LIT(KUNINET,"uninet");

	aIapInfoList.Reset();

	//得到网络类型
	TNetWorkType newWorkType = CPhoneInfo::GetNetWorkType();

	TBuf<KCommsDbSvrMaxFieldLength> commdbName;
	TBuf<KCommsDbSvrMaxColumnNameLength> apn;

	//	获得接入点名字
	CCommsDatabase *commsDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(commsDb);
	CCommsDbTableView *tableView = commsDb->OpenTableLC(TPtrC(OUTGOING_GPRS));
	TInt err = tableView->GotoFirstRecord();
	while (err == KErrNone)
		{
		tableView->ReadTextL(TPtrC(GPRS_APN), apn);
		apn.LowerCase();

		if (newWorkType == ENetWorkCM)//移动
			{
			if (apn.Compare(KCMWAP) == 0 || apn.Compare(KCMNET) == 0)
				{
				tableView->ReadTextL(TPtrC(COMMDB_NAME), commdbName);
				TIapInfo info;
				info.iIapName.Copy(commdbName);
				info.iId = KMaxTUint32;
				aIapInfoList.Append(info);
				}
			}
		else if (newWorkType == ENetWorkUN)//联通
			{
			if (apn.Compare(K3GWAP) == 0 || apn.Compare(K3GNET) == 0
					|| apn.Compare(KUNIWAP) == 0 || apn.Compare(KUNINET) == 0)
				{
				tableView->ReadTextL(TPtrC(COMMDB_NAME), commdbName);
				TIapInfo info;
				info.iIapName.Copy(commdbName);
				info.iId = KMaxTUint32;
				aIapInfoList.Append(info);
				}
			}
		err = tableView->GotoNextRecord();
		}
	CleanupStack::PopAndDestroy(2, commsDb); // tableView, commsDb


	if (aIapInfoList.Count() == 0)
		return;

	//====================================================================================================
	//	根据接入点名字查找接入点id
	CCommsDatabase* commDb = CCommsDatabase::NewL(EDatabaseTypeIAP);
	CleanupStack::PushL(commDb);
	CCommsDbTableView* commView = commDb->OpenTableLC(TPtrC(IAP));
	if (commView->GotoFirstRecord() == KErrNone)
		{
		do
			{
			commView->ReadTextL(TPtrC(COMMDB_NAME), commdbName);
			for (TInt i = aIapInfoList.Count() - 1; i >= 0; i--)
				{
				if (aIapInfoList[i].iIapName.Compare(commdbName) == 0)
					{
					commView->ReadUintL(TPtrC(COMMDB_ID), aIapInfoList[i].iId);
					break;
					}
				}
			}
		while (commView->GotoNextRecord() == KErrNone);
		}
	CleanupStack::PopAndDestroy(/*commView*/);
	CleanupStack::PopAndDestroy(/*commDb*/);

	//清除没有查到的接入点
	for (TInt i = aIapInfoList.Count() - 1; i >= 0; i--)
		{
		if (aIapInfoList[i].iId == KMaxTUint32)
			{
			aIapInfoList.Remove(i);
			}
		}
	}
